#include "stm32f1xx_hal.h"
#include "oled.h"

#define OLED_ADDR 0x78  // OLED I2C 地址
#define OLED_CMD  0x00  // 写命令
#define OLED_DATA 0x40  // 写数据




 
uint8_t F8X16[] = {
0x10,0x60,0x02,0x8C,0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
0x04,0x04,0x7E,0x01,0x40,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00,/*"温",0*//* (16 X 16 , 宋体 )*/
0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,
0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00,/*"度",1*//* (16 X 16 , 宋体 )*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"：",2*//* (16 X 16 , 宋体 )*/
};










extern I2C_HandleTypeDef hi2c2;

// 向 OLED 发送命令
void OLED_WriteCmd(uint8_t cmd)
{
    uint8_t data[2] = {OLED_CMD, cmd};
    HAL_I2C_Master_Transmit(&hi2c2, OLED_ADDR, data, 2, 100);
}

// 向 OLED 发送数据
void OLED_WriteData(uint8_t data)
{
    uint8_t buf[2] = {OLED_DATA, data};
    HAL_I2C_Master_Transmit(&hi2c2, OLED_ADDR, buf, 2, 100);
}

// OLED 初始化
void OLED_Init(void)
{
    HAL_Delay(100);

    OLED_WriteCmd(0xAE); // 关闭显示
    OLED_WriteCmd(0x20); // 设置内存地址模式
    OLED_WriteCmd(0x10); // 水平地址模式
    OLED_WriteCmd(0xB0); // 设置页地址
    OLED_WriteCmd(0xC8); // 设置 COM 扫描方向
    OLED_WriteCmd(0x00); // 设置列地址低 4 位
    OLED_WriteCmd(0x10); // 设置列地址高 4 位
    OLED_WriteCmd(0x40); // 设置显示开始行
    OLED_WriteCmd(0x81); // 设置对比度
    OLED_WriteCmd(0xFF);
    OLED_WriteCmd(0xA1); // 设置段重映射
    OLED_WriteCmd(0xA6); // 设置正常显示
    OLED_WriteCmd(0xA8); // 设置多路复用率
    OLED_WriteCmd(0x3F);
    OLED_WriteCmd(0xA4); // 全局显示开启
    OLED_WriteCmd(0xD3); // 设置显示偏移
    OLED_WriteCmd(0x00);
    OLED_WriteCmd(0xD5); // 设置显示时钟分频比/振荡器频率
    OLED_WriteCmd(0xF0);
    OLED_WriteCmd(0xD9); // 设置预充电周期
    OLED_WriteCmd(0x22);
    OLED_WriteCmd(0xDA); // 设置 COM 引脚硬件配置
    OLED_WriteCmd(0x12);
    OLED_WriteCmd(0xDB); // 设置 VCOMH 取消选择级别
    OLED_WriteCmd(0x20);
    OLED_WriteCmd(0x8D); // 设置充电泵
    OLED_WriteCmd(0x14);
    OLED_WriteCmd(0xAF); // 开启显示
}

// 设置光标位置
void OLED_SetPos(uint8_t x, uint8_t y)
{
    OLED_WriteCmd(0xB0 + y);
    OLED_WriteCmd(((x & 0xF0) >> 4) | 0x10);
    OLED_WriteCmd((x & 0x0F) | 0x00);
}

// 清屏
void OLED_Clear(void)
{
    uint8_t i, n;
    for (i = 0; i < 8; i++)
    {
        OLED_WriteCmd(0xB0 + i);
        OLED_WriteCmd(0x00);
        OLED_WriteCmd(0x10);
        for (n = 0; n < 128; n++)
        {
            OLED_WriteData(0x00);
        }
    }
}

// 显示一个字符
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr)
{
    uint8_t c = 0, i = 0;
    c = chr - ' ';
    if (x > 128 - 8)
    {
        x = 0;
        y = y + 2;
    }
    OLED_SetPos(x, y);
    for (i = 0; i < 8; i++)
    {
        OLED_WriteData(F8X16[c * 16 + i]);
    }
    OLED_SetPos(x, y + 1);
    for (i = 0; i < 8; i++)
    {
        OLED_WriteData(F8X16[c * 16 + i + 8]);
    }
}

// 显示字符串
void OLED_ShowString(uint8_t x, uint8_t y, uint8_t *chr)
{
    uint8_t j = 0;
    while (chr[j] != '\0')
    {
        OLED_ShowChar(x, y, chr[j]);
        x += 8;
        if (x > 120)
        {
            x = 0;
            y += 2;
        }
        j++;
    }
}    